package com.detection.yolo.utils;

import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.util.logging.Logger;

public class OpenCVChineseUtil {

    private static final Logger log = Logger.getLogger(OpenCVChineseUtil.class.getName());

    public static void drawText(Mat mat, String cnText, String enText, Point origin, Scalar color, Font font, int fontSize) {
        try {
            BufferedImage bufferedImage = matToBufferedImage(mat);
            Graphics2D g2d = bufferedImage.createGraphics();
            fontSize = fontSize / 2;
            if (font == null) {
                font = new Font("SimHei", Font.PLAIN, fontSize);
            }
            g2d.setFont(font);

            Color awtColor = new Color((int) color.val[2], (int) color.val[1], (int) color.val[0]);
            g2d.setColor(awtColor);

            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

            double textX = origin.x;
            double textY = origin.y + fontSize - 5; // 调整 baseline，更贴近原 putText

            g2d.drawString(cnText, (float) textX, (float) textY);
            g2d.dispose();

            // ✅ 安全地写回 Mat
            bufferedImageToMat(bufferedImage, mat);

        } catch (Exception e) {
            log.warning("Failed to draw Chinese text: " + e.getMessage() + ". Falling back to OpenCV putText.");
            Point fallbackOrigin = new Point(origin.x, origin.y + 5);
            Imgproc.putText(mat, enText, fallbackOrigin, Imgproc.FONT_HERSHEY_SIMPLEX,
                    fontSize / 15.0, color, Math.max(1, fontSize / 5));
        }
    }

    // ✅ 安全的 Mat -> BufferedImage 转换
    private static BufferedImage matToBufferedImage(Mat mat) {
        int width = mat.cols();
        int height = mat.rows();
        int type = BufferedImage.TYPE_3BYTE_BGR;

        byte[] data = new byte[width * height * 3]; // 3 channels
        mat.get(0, 0, data);

        BufferedImage image = new BufferedImage(width, height, type);
        image.getRaster().setDataElements(0, 0, width, height, data);
        return image;
    }

    // ✅ 安全的 BufferedImage -> Mat 转换（避免 DataBufferByte 强转）
    private static void bufferedImageToMat(BufferedImage image, Mat mat) {
        int width = image.getWidth();
        int height = image.getHeight();
        byte[] data = new byte[width * height * 3];

        WritableRaster raster = image.getRaster();
        raster.getDataElements(0, 0, width, height, data); // 直接获取字节数组

        mat.put(0, 0, data);
    }
}
